package com.example.result

import android.content.Context
import android.os.Build
import android.os.Looper
import android.os.Trace
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.LayoutInflaterCompat
import kotlin.time.ExperimentalTime
import kotlin.time.measureTimedValue

class TimeProfile {
    companion object {
        val times = HashMap<String, Long>()
        val onCreate = "onCreate"
        val onViewCreated = "onViewCreated"
        val FRAGMENT_ALL = "FRAGMENT_ALL"
        val FIRST_LAYOUT = "FIRST_LAYOUT"
        val FIRST_DRAW = "FIRST_DRAW"
        val TOTLE = "TOTLE"
        val APPLICATION = "APPLICATION"
        val APP_BEFORE_ACT = "APP_BEFORE_ACT"
        val canNotTraceSet = HashSet<String>()

        init {
            canNotTraceSet.add(FRAGMENT_ALL)
            canNotTraceSet.add(FIRST_LAYOUT)
            canNotTraceSet.add(FIRST_DRAW)
            canNotTraceSet.add(TOTLE)
            canNotTraceSet.add(APP_BEFORE_ACT)
//            canNotTraceSet.add(APPLICATION)
        }

        fun end(vararg tag: String) {
            tag.forEach {
                times[it]?.also { start ->
                    Log.d("TimeProfile ${it}", (System.currentTimeMillis() - start).toString())
                    times.remove(it)
                    if (!canNotTraceSet.contains(it)) {
                        Trace.endSection()
                    }
                }
            }
        }

        @JvmStatic
        fun begin(vararg tag: String) {
            val time = System.currentTimeMillis()
            tag.forEach {
                times.put(it, time)
                if (!canNotTraceSet.contains(it)) {
                    Trace.beginSection(it)
                }
            }
        }

        fun listenerMainLoop() {
            var i = 0
            var isEnd = false
            Looper.getMainLooper().setMessageLogging {
                if (!isEnd) {
                    TimeProfile.begin(i.toString())
                    isEnd = true
                } else {
                    TimeProfile.end(i.toString())
                    i++
                    isEnd = false
                }
            }
        }

        @ExperimentalTime
        fun inflateListener(activity: AppCompatActivity) {
            LayoutInflaterCompat.setFactory2(
                LayoutInflater.from(activity),
                object : LayoutInflater.Factory2 {
                    override fun onCreateView(
                        parent: View?,
                        name: String,
                        context: Context,
                        attrs: AttributeSet
                    ): View? {
                        //'测量构建单个View耗时'
                        val (view, duration) = measureTimedValue {
                            activity.delegate.createView(
                                parent,
                                name,
                                context,
                                attrs
                            )
                        }
                        //'累加构建视图耗时'
                        if (duration.inWholeMilliseconds >= 1) {
                            Log.d(
                                "onCreate_1",
                                "view=${view?.let { it::class.java.simpleName }} duration=${duration}  "
                            )
                        }
                        return view


                    }

                    override fun onCreateView(
                        name: String,
                        context: Context,
                        attrs: AttributeSet
                    ): View? {
                        return null
                    }

                })
        }

        fun listenerLayoutAndDraw(view: View) {
            TimeProfile.begin(TimeProfile.FIRST_LAYOUT)
            view.let {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    it.viewTreeObserver.addOnGlobalLayoutListener {

                        if (TimeProfile.times.containsKey(TimeProfile.FIRST_LAYOUT)) {
                            TimeProfile.begin(TimeProfile.FIRST_DRAW)
                        }
                        TimeProfile.end(TimeProfile.FIRST_LAYOUT)
                    }
                    it.viewTreeObserver.addOnDrawListener {
                        TimeProfile.end(TimeProfile.FIRST_DRAW)
                        TimeProfile.end(TimeProfile.TOTLE)

                    }
                }

            }
        }

    }
}